﻿// ------------------------------------------------------------------------------------------------
//  <copyright file="Block.cs" company="Iveely">
//    Copyright (c) Iveely Liu.  All rights reserved.
//  </copyright>
//  
//  <Create Time>
//    12/03/2012 20:12 
//  </Create Time>
//  
//  <contact owner>
//    liufanping@iveely.com 
//  </contact owner>
//  -----------------------------------------------------------------------------------------------

#region

using System;
using System.Collections;
using System.Collections.Generic;
using IveelySE.Common;
using IveelySE.Config;

#endregion

namespace IveelySE.IDFS.Store
{
    /// <summary>
    ///   文件块（一个大文件在一个节点上只有一个块，一个块可以由多个片段组成）
    /// </summary>
    [Serializable]
    public class Block
    {
        /// <summary>
        ///   代码片段栈(为什么栈？因为栈顶是当前正在活跃的文件，更加利索活跃文件的操作)
        /// </summary>
        private static readonly List<Fragment> List = new List<Fragment>();

        /// <summary>
        ///   存储信息，记录每一个数据对应的段
        /// </summary>
        private static Hashtable _storeInfo = new Hashtable();

        /// <summary>
        ///   大数据存储原始文件名（
        /// </summary>
        public string FileName { get; set; }

        /// <summary>
        ///   向此快中添加数据
        ///   <param name="data"> 需要添加的数据 </param>
        ///   <param name="size"> 所添加数据的大小 </param>
        /// </summary>
        public bool Add(PObject data, int size)
        {
            //从栈中取出当前活跃块
            //如果栈中不存在
            if (List.Count == 0)
            {
                //新建片段
                var fragment = new Fragment(data.FileName + "." + DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss") + ".Page_unIndex");
                //执行插入(新插入不需要判断是否大于其片段容量)
                fragment.Add(data, size);
                //加入到栈中
                List.Add(fragment);
            }
            //如果栈中不为空
            else
            {
                //在顶部片段中插入数据,如果失败
                if (!List[List.Count - 1].Add(data, size))
                {
                    //新建片段再次插入
                    var fragment =
                        new Fragment(data.FileName + "." + DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss") + ".Page_unIndex");
                    //执行插入
                    fragment.Add(data, size);
                    //加入到栈中
                    List.Add(fragment);

                }
            }
            return true;
        }


        ///// <summary>
        ///// 查找某行的记录
        ///// </summary>
        ///// <param name="rowNum"></param>
        ///// <returns></returns>
        //public PObject Find(int rowNum)
        //{
        //    //第一步找到对应的片段
        //    int framNum = rowNum / 100;
        //    //如果大于了记录中的值
        //    if (framNum - 1 > List.Count)
        //    {
        //        return null;
        //    }
        //    return List[framNum].Find(rowNum % 100);
        //}

        public PObject Find(int dataId)
        {
            string fragmentId = _storeInfo[dataId].ToString();
            return Fragment.Find(fragmentId, dataId);
        }

        public PObject FindWhenSearch(int dataId)
        {
            try
            {
                //例如：fragmentId=Page.152
                string fragmentId = _storeInfo[dataId].ToString();
                //但实际会减1（后期Fix：在索引的时候需要更改）

                #region 以下代码下版本需要处理

                //fragmentId = fragmentId.Split('.')[0] +"."+ (int.Parse(fragmentId.Split('.')[1].ToString()) - 1);

                #endregion

                return Fragment.FindWhenSearch(fragmentId, dataId);
            }
            catch (Exception)
            {
            }
            return null;
        }

        public static  void AddToStore(int dataId, string fragmentId)
        {
            _storeInfo.Add(dataId, fragmentId);
        }

        public static void SaveStoreInfo(string fileName)
        {
            Serialize.Serailzable(_storeInfo, Application.GetCrawlerTempDir() + fileName + "Store");
        }

        public static void LoadStoreInfo(string fileName)
        {
            Object obj = Serialize.UnSerailzable(fileName + "Store");
            if (obj != null)
            {
                _storeInfo = (Hashtable)obj;
            }
            else
            {
                _storeInfo = new Hashtable();
            }
        }
    }
}